package com.itheima.service.impl;

import com.alibaba.fastjson.JSON;
import com.itheima.dto.SearchDto;
import com.itheima.pojo.Good;
import com.itheima.service.SearchService;
import com.itheima.support.GoodResult;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author YYP
 * @date 2020/12/19
 */
@Service
public class SearchServiceImpl implements SearchService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;


    @Override
    public GoodResult goodsSearch(SearchDto searchDto) throws IOException {
        ArrayList<Good> list = new ArrayList<>();
        //创建SearchRequest指定索引库名称
        SearchRequest searchRequest = new SearchRequest("goods");
        //创建Builder
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //构建查询条件

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        //boolQueryBuilder.should(QueryBuilders.matchQuery("name","手机电视"));
        if (searchDto.getKeyword()!=null){
            //在商品标题上检索
        /*    FuzzyQueryBuilder fuzzyQuery = QueryBuilders.fuzzyQuery("name", searchDto.getKeyword())
                    .fuzziness(Fuzziness.TWO);*/
            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", searchDto.getKeyword());
            boolQueryBuilder.must(matchQueryBuilder);
        }

        //范围
        if (searchDto.getMaxPrice() != 0){
            RangeQueryBuilder priceRangeBuilder = QueryBuilders.rangeQuery("price");
            if (searchDto.getMaxPrice() == -1) {
                priceRangeBuilder.gte(searchDto.getMinPrice());
            }else {
                priceRangeBuilder.lte(searchDto.getMaxPrice()).gte(searchDto.getMinPrice());
            }
            boolQueryBuilder.filter(priceRangeBuilder);
        }
  /*      RangeQueryBuilder priceRangeBuilder = QueryBuilders.rangeQuery("price")
                .gte(searchDto.getMinPrice())
                .lte(searchDto.getMaxPrice());
        boolQueryBuilder.filter(priceRangeBuilder);*/
        sourceBuilder.query(boolQueryBuilder);
        //排序
        //sourceBuilder.sort("price", SortOrder.ASC);
        if (searchDto.isSortByPrice()) {
            if (searchDto.isDescFlag()){
                sourceBuilder.sort("price", SortOrder.DESC);
            }
            else {
                sourceBuilder.sort("price",SortOrder.ASC);
            }
        }
        //设置分页参数
        int page = searchDto.getCurrentPage();
        int size = searchDto.getPageSize();
        int from = (page - 1) * size;
        sourceBuilder.from(from);
        sourceBuilder.size(size);

        //设置高亮三要素
        HighlightBuilder highlight = SearchSourceBuilder.highlight();
        highlight.field("name");
        highlight.preTags("<font color='red'>");
        highlight.postTags("</font>");
        sourceBuilder.highlighter(highlight);

        //searchRequest.source(builder)  添加到查询结果中
        searchRequest.source(sourceBuilder);
        //发起请求
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        //解析结果
        SearchHits searchHits = response.getHits();
        long value = searchHits.getTotalHits().value;
        System.out.println("total:"+value);
        for (SearchHit searchHit : searchHits) {
            String goodJson = searchHit.getSourceAsString();
            Good good = JSON.parseObject(goodJson, Good.class);

            // ***** 解析高亮数据
            HighlightField highlightField = searchHit.getHighlightFields().get("name");
            // get("高亮显示域名称")
            Text[] fragments = highlightField.getFragments();
            String newName = StringUtils.join(fragments);
            // 判断如果是可以获取到数据则更新到商品对象中
            if (StringUtils.isNotBlank(newName)){
                good.setName(newName);

                list.add(good);
            }
        }
        return new GoodResult(list,value) ;
    }
}
